/**
 * Odontosis - (2008 - Eclipse 3.3 - JDK1.6 Update 3) 
 */
package com.odontosis.dao;

import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import com.odontosis.as.OdontosisDataAccessObject;
import com.odontosis.entidade.Paciente;
import com.odontosis.util.HibernateUtil;
import com.odontosis.util.StringUtilsOdontosis;

/**
 * Data Access Object de paciente.
 * @author Oto
 * ltima modificao: $Author$<br>
 * Verso: $Revision$ $Date$
 */
public class PacienteDAO extends OdontosisDataAccessObject<Paciente> {
	
	@SuppressWarnings("unchecked")
	public Collection<Paciente> pesquisarPorNomeECodigo(String codigo, String nome, boolean comIpsm){
		HibernateUtil.closeSession();
		Session session = HibernateUtil.currentSession();
		Criteria criteria = session.createCriteria(Paciente.class);
		if(!StringUtilsOdontosis.isVazia(nome)){
			criteria.add(Restrictions.like("nome", nome, MatchMode.ANYWHERE));
		}
		if(!StringUtilsOdontosis.isVazia(codigo)){
			criteria.add(Restrictions.eq("numeroPasta",codigo));
		}
		if(comIpsm) {
			criteria.add(Restrictions.isNotNull("ipsm"));
			criteria.add(Restrictions.not(Restrictions.eq("ipsm", "")));
		}
		criteria.add(Restrictions.eq("ativo", true));
		criteria.addOrder(Order.desc("id"));
		criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		return criteria.list();
	}
	
	public Paciente buscarPorNumeroPaciente(String codigo){
		HibernateUtil.closeSession();
		Session session = HibernateUtil.currentSession();
		Criteria criteria = session.createCriteria(Paciente.class);
		criteria.add(Restrictions.like("pasta",codigo));
		criteria.add(Restrictions.eq("ativo", true));
		return (Paciente) criteria.uniqueResult();
		
	}
	
	@SuppressWarnings("unchecked")
	public List<Paciente> buscarPacienteEmTratamentoOuEmAcompanhamento(){
		Session session = HibernateUtil.currentSession();
		Criteria criteria = session.createCriteria(Paciente.class);
		criteria.add(Restrictions.or(Restrictions.like("situacaoPaciente", "0"), (Restrictions.like("situacaoPaciente", "4"))));
		criteria.add(Restrictions.eq("ativo", true));
		return  criteria.list();
	}
	
	@SuppressWarnings("unchecked")
	public List<Paciente> buscarPacienteEmTratamentoOuEmAcompanhamento(String codigo, String nome, int maxResultado){
		Session session = HibernateUtil.currentSession();
		Criteria criteria = session.createCriteria(Paciente.class);
		if(!StringUtilsOdontosis.isVazia(nome)){
			criteria.add(Restrictions.like("nome", nome, MatchMode.ANYWHERE));
		}
		if(!StringUtilsOdontosis.isVazia(codigo)){
			criteria.add(Restrictions.eq("id",new Long(codigo)));
		}
		criteria.add(Restrictions.or(Restrictions.like("situacaoPaciente", "0"), (Restrictions.like("situacaoPaciente", "4"))));
		criteria.add(Restrictions.eq("ativo", true));
		criteria.addOrder(Order.asc("nome"));
		
		criteria.setMaxResults(maxResultado);
		criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
		return  criteria.list();
	}
	
	@SuppressWarnings("unchecked")
	public List<Paciente> pesquisarPorNome(String nome){
		HibernateUtil.closeSession();
		Session session = HibernateUtil.currentSession();
		Criteria criteria = session.createCriteria(Paciente.class);
		criteria.add(Restrictions.like("nome",nome,MatchMode.ANYWHERE));
		criteria.add(Restrictions.eq("ativo", true));
		criteria.setMaxResults(30);
		criteria.addOrder(Order.asc("nome"));
		return criteria.list();
	}
	
	@SuppressWarnings("unchecked")
	public List<Paciente> pesquisarParaAutoComplete(String parte){
		HibernateUtil.closeSession();
		Session session = HibernateUtil.currentSession();
		Criteria criteria = session.createCriteria(Paciente.class);
		criteria.add(Restrictions.or(Restrictions.like("nome",parte,MatchMode.ANYWHERE), Restrictions.like("numeroPasta", parte)));
		criteria.add(Restrictions.eq("ativo", true));
		criteria.setMaxResults(30);
		criteria.addOrder(Order.asc("nome"));
		return criteria.list();
	}
	
	public List<Paciente> pesquisarParaAutoCompleteComIpsm(String parte){
		HibernateUtil.closeSession();
		Session session = HibernateUtil.currentSession();
		Criteria criteria = session.createCriteria(Paciente.class);
		criteria.add(Restrictions.or(Restrictions.like("nome",parte,MatchMode.ANYWHERE), Restrictions.like("numeroPasta", parte)));
		criteria.add(Restrictions.eq("ativo", true));
		criteria.add(Restrictions.isNotNull("ipsm"));
		criteria.add(Restrictions.not(Restrictions.eq("ipsm", "")));
		criteria.setMaxResults(30);
		criteria.addOrder(Order.asc("nome"));
		return criteria.list();
	}
	
	public Integer buscarMaiorNumeroPasta(){
		HibernateUtil.closeSession();
		Session session = HibernateUtil.currentSession();
		Query query = session.createSQLQuery("select max(numeropasta) from paciente");
		return (Integer) query.uniqueResult();
	}

	@Override
	public void saveOrUpdate(Paciente entidade) {
		HibernateUtil.closeSession();
		Session session = HibernateUtil.currentSession();
		Transaction transaction = session.beginTransaction();
		try {
			session.saveOrUpdate(entidade);
			transaction.commit();
		} catch (Exception e) {
			transaction.rollback();
			e.printStackTrace();
			throw new RuntimeException("Erro ao salvar ou updatar entidade");
		}
	}
	
	public Collection<Paciente> pesquisarPorNomeECodigo(String codigo, String nome,boolean comIpsm, boolean comFiodSemPericia) {
		HibernateUtil.closeSession();
		Session session = HibernateUtil.currentSession();
		String hql = "Select distinct sc.paciente from ServicoConveniado sc  where " +
				"  sc.paciente.nome like :nome " + 
				" and sc.paciente.numeroPasta like :codigo " +
				" and sc.dataPericia is null " +
				" and sc.paciente.virNoRelatorio = true ";
		
		Query query = session.createQuery(hql);
		query.setParameter("nome","%" + nome + "%");
		query.setParameter("codigo", "%" + codigo + "%");
		Collection<Paciente> pacientes = query.list();
		return pacientes;
	}
	
	public List<Paciente> pesquisarPorAniversario(Date inicio, Date fim, String nomePaciente) {
		Calendar calInicio = Calendar.getInstance();
		calInicio.setTime(inicio);
		Calendar calFim = Calendar.getInstance();
		calFim.setTime(fim);
		Integer diaInicio = calInicio.get(Calendar.DAY_OF_MONTH);
		Integer mesInicio = calInicio.get(Calendar.MONTH) + 1;
		Integer diaFim = calFim.get(Calendar.DAY_OF_MONTH);
		Integer mesFim = calFim.get(Calendar.MONTH) + 1;
		
		int periodoInicio = mesInicio * 100 + diaInicio;
		int periodofim = mesFim * 100 + diaFim;
		
		String hql = "FROM Paciente" +
		" WHERE " +
		" MONTH(dataNascimento) * 100 + DAY(dataNascimento) between :inicio and :fim  " +
		" AND ativo = TRUE " +
		" AND dataNascimento IS NOT NULL " +
		" AND nome LIKE :nome " +
		" ORDER BY MONTH(dataNascimento),DAY(dataNascimento),nome ";
		
		/*
		" ((DAY(dataNascimento) >= :diainicio AND MONTH(dataNascimento) = :mesinicio) "+ //-- mes inicio igual ao aniversario e dia maior ou igual ao aniversario 
		" OR(DAY(dataNascimento) <= :diafim AND MONTH(dataNascimento) = :mesfim)  " + //-- mes fim igual ao aniversario e dia menor ou igual ao aniversario
		" OR (MONTH(dataNascimento) > :mesinicio AND MONTH(dataNascimento) < :mesfim))  " + //-- mes do aniversario entre mes inicio e fim 
		*/
		
		Query query = getSession().createQuery(hql);
		query.setInteger("inicio", periodoInicio);
		query.setInteger("fim", periodofim);
		query.setParameter("nome", "%" + nomePaciente + "%");
		
		return query.list();
		
	}
	
	
}
